import HelperFunctions as HF
import numpy as np
from numpy import array
import csv
import random
from datetime import datetime
from time import strftime

'''
calculate
'''

def getCurTime():
    """
    get current time
    Return value of the date string format(%Y-%m-%d %H:%M:%S)
    """
    format='%Y-%m-%d %H:%M:%S'
    sdate = None
    cdate = datetime.now()
    try:
        sdate = cdate.strftime(format)
    except:
        raise ValueError
    return sdate

def get_inputs():
    """Given the list of inputs for the script when run, return an object
    containing the variables for the script"""
    try:
        '''
        sInputFC = HF.pGP.GetParameterAsText(0)                     # Input Feature Class
        sField_Ob = HF.pGP.GetParameterAsText(1).upper()              # Observation Field Name
        sField_Pop = HF.pGP.GetParameterAsText(2).upper()                # Population Field Name
        sCongtiguityFC = HF.pGP.GetParameterAsText(3)                # Congtiguity File (.csv) with "ID1" and "ID2"
        sOutputFC = HF.pGP.GetParameterAsText(4)                  # Output Feature Class
        '''
        sInputFC = "C:/_DATA/CancerData/test/Jan15/TP1000_1m_1000cancer.shp"
        #sField_Ob = "CANCER2"
        sField_Pop = "pop"
        #sCongtiguityFC = "C:\_WORK\MyPythonWork\CreateData\TP1000_cancer__Congtiguity.csv" 
        #sOutputFC = "C:\_WORK\MyPythonWork\CreateData\TP1000_cancer__EBS.shp"
        #sInputCSV = "C:\SS_CLK_pop_min_10000_67reg_cancer2.csv"
        

  
    except: raise HF.ReportError (HF.msgParseErr)
    
    #Make a generic object, populate it with our variables, then return it
    try:
        obj = HF.Gen()
        obj.add('sInputFC',sInputFC)
        #obj.add('sField_Ob',sField_Ob)
        obj.add('sField_Pop', sField_Pop)
        #obj.add('sCongtiguityFC', sCongtiguityFC)
        #obj.add('sOutputFC', sOutputFC)
        #obj.add('sInputCSV', sInputCSV)

    except: raise HF.ReportError (HF.msgInputsErr)

    return obj

def build_value_lists_from_csv(cancerFN):
    sKey = np.array([])
    #read contiguity file
    fn = inputAttriCSV

    #print "Strat building csv lists..."

    ra = csv.DictReader(file(fn), dialect="excel")
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp = [int(float(record["ID"])), int(float(record[cancerFN])),int(float(record[popFN])),float(record["Area"])]
        #print temp
        sKey =np.append(sKey, temp)
    sKey.shape=(-1,4)
    return sKey


def build_value_lists(cancerFN):
    """Reads through feature table extracting geometry and field info.
       Returns this information in dictionary structures."""

    pRows = HF.pGP.SearchCursor(inputs.sInputFC)
    # pRows = pGP.SearchCursor(inputs.sOutputFC)
    pRow = pRows.Next()
    sKey = np.array([])
    lsBadRecs = []
    iBadRecCnt = 0
    iRec = 0 


    #print "Strat building attribute lists..."
    
    
    while pRow <> None:
        iRec = iRec + 1
        try:
            dTemp = []
            dTemp.append(pRow.GetValue("FID"))
            dTemp.append(pRow.GetValue(cancerFN))
            dTemp.append(pRow.GetValue(inputs.sField_Pop))
            dTemp.append(pRow.GetValue("Area"))
            sKey=np.append(sKey,dTemp)
        except:
            iBadRecCnt += 1
        pRow = pRows.Next()
    
    #print iBadRecCnt     
    # Report any problems encountered reading feature input data.
    if iBadRecCnt:
        sMessage = HF.msgReadErr % (iBadRecCnt, iRec)
        HF.pGP.AddWarning (sMessage)
        HF.pGP.AddWarning(`lsBadRecs`)


    sKey.shape = (-1,4)
    
    #print sKey    
    return sKey #[[FID, cancer, pop],[FID, cancer, pop, area], ... ]

def build_csv_list(inputCSV):
    spDissovle = np.array([],dtype=int)
    #read contiguity file
    fn = inputCSV

    #print "Strat building csv lists..."

    ra = csv.DictReader(file(fn), dialect="excel")       
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp = [int(float(record[ra.fieldnames[0]])), int(float(record[ra.fieldnames[-1]]))]
        #print temp
        spDissovle =np.append(spDissovle, temp)
    spDissovle.shape=(-1,2)
    return spDissovle

def find_same_region(regionID):
    # return the original item id list within a region 
    iLen = csv_attri.shape
    i = 0
    temp = []
    while i < iLen[0]:
        if csv_attri[i,1] == regionID:
            temp = np.append(temp, csv_attri[i,0])
        i = i + 1
    return temp

def cal_region_rate(regionList):
    # calculate rate = cancer/pop for each region
    # return a list
    iLen = regionList.shape
    reg_rate = np.array([])

    i = 0
    while i < iLen[0]:
        temp = find_same_region(regionList[i])
        temp_cancer = 0
        temp_pop = 0
        for item in temp:
            temp_cancer = temp_cancer + attri[item, 1]
            temp_pop = temp_pop + attri[item, 2]
        temp_rate = temp_cancer/temp_pop
        reg_rate = np.append(reg_rate, [regionList[i], temp_rate])
        i = i + 1
    reg_rate.shape = (-1, 2)
    return reg_rate
    
def find_rep_region(unitList, listID):
    temp = np.array([])
    totalPop = 0
    totalCancer = 0
    totalArea = 0
    i = 0
    for item in unitList:
        temp = np.append(temp, int(csv_attri[item,1]))
        totalPop = totalPop + attri[item, 2]
        totalCancer = totalCancer + attri[item, 1]
        totalArea = totalArea + attri[item, 3]
        i = i + 1
    #temp.shape = (-1, 2)
    dis_region = np.unique(temp) # distinct region ID in the unitList
    reg_pop = np.array([])
    reg_cancer = np.array([])
    temp_reg_rate = np.array([])
    reg_area = np.array([])
    temp_type_two_error = np.array([])
    
    for region in dis_region:
        temp_pop = 0
        temp_cancer = 0
        temp_area = 0
        for unit in unitList:
            if int(csv_attri[unit, 1] ) == int(region):
                temp_pop = temp_pop + attri[unit, 2]
                temp_cancer = temp_cancer +  attri[unit, 1]
                temp_area = temp_area + attri[unit, 3]
        reg_pop = np.append(reg_pop, int(temp_pop))
        reg_cancer = np.append(reg_cancer, int(temp_cancer))
        #temp_reg_rate = np.append(temp_reg_rate, temp_cancer/temp_pop)
        temp_reg_rate = np.append(temp_reg_rate, reg_rate[region, 1])
        reg_area = np.append(reg_area, temp_area)
    #print "reg_rate = ", reg_rate

    temp_max_id = 0
    
    
    if returnID == 0:     
        # return max_pop
        # find the maximum pop and its id 
        i = 0
        temp_max_pop = 0
        temp_max_pop_id = 0
        for pop in reg_pop:
            if pop > temp_max_pop:
                temp_max_pop = pop
                temp_max_pop_id = i
            i = i + 1
        temp_max_id = temp_max_pop_id    
    elif returnID == 1:
        # return max_cancer
        # find the maximum cancer and its id    
        i = 0
        temp_max_cancer = 0
        temp_max_cancer_id = 0
        for cancer in reg_cancer:
            if cancer > temp_max_cancer:
                temp_max_cancer = cancer
                temp_max_cancer_id = i
            i = i + 1
        temp_max_id = temp_max_cancer_id    
    elif returnID == 2: 
        # return max or min cancer
        if listID in [1,3,4,7]: # high risk area, return max cancer id
            # find the maximum rate and its id
            i = 0
            temp_max_rate = 0
            temp_max_rate_id = 0
            for rate in temp_reg_rate:
                if rate > temp_max_rate:
                    temp_max_rate = rate
                    temp_max_rate_id = i
                i = i + 1
            temp_max_id = temp_max_rate_id 
        elif listID in [2,5,6]: # low risk area, return min cancer id
            # find the minimum rate and its id
            i = 0
            temp_min_rate = 1
            temp_min_rate_id = 0
            for rate in temp_reg_rate:
                if rate < temp_min_rate:
                    temp_min_rate = rate
                    temp_min_rate_id = i
                i = i + 1
            temp_max_id = temp_min_rate_id 
    elif returnID == 3:
        # return max_area
        # find the maximum area and its id    
        i = 0
        temp_max_area = 0
        temp_max_area_id = 0
        for area in reg_area:
            if area > temp_max_area:
                temp_max_area = area
                temp_max_area_id = i
            i = i + 1
        temp_max_id = temp_max_area_id
        if  reg_area[temp_max_id]/totalArea < 0.5:
            temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 3])
            #print sField_Ob, "'s region ", listID, "does not have half area of its representive risk area"
        
    if  reg_pop[temp_max_id]/totalPop < 0.5:
        temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 0])
        #print sField_Ob, "'s region ", listID, "does not have half pop of its representive risk area"
    if  reg_cancer[temp_max_id]/totalCancer < 0.5:
        temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, int(dis_region[temp_max_id]), 1])
        #print sField_Ob, "'s region ", listID, "does not have half cancer of its representive risk area"
    
    return int(dis_region[temp_max_id]), totalPop, totalCancer, reg_pop[temp_max_id], reg_cancer[temp_max_id], temp_type_two_error

def find_max_id(list):
    # return the id of the maximum value
    i = 0
    temp_max = 0
    temp_max_id = 0
    
    for item in list:
        if item > temp_max:
            temp_max = item
            temp_max_id = i
        i = i + 1
    return temp_max_id           

def find_min_id(list):
    # return the id of the maximum value
    i = 0
    temp_min = 1000000
    temp_min_id = 0
    
    for item in list:
        if item < temp_min:
            temp_min = item
            temp_min_id = i
        i = i + 1
    return temp_min_id

def calMeaser():
    H1 = [8,16,844,915,919,921,923,924]
    L2 = [5,103,106,513,517,518,520,531,534,535,536,541]
    H3 = [63,265,267,268,333,336,337,339,340,342,343,348]
    H4 = [13,174,178,198,886,887,888,889,890]
    L5 = [146,171,182,810,811,814,815,864,867]
    L6 = [20,133,692,694,695,696,698,702,705]
    H7 = [69,70,87,88,369,370,372,442,443]

    high_risk_region = np.array([])
    low_risk_regioin = np.array([])
    tempPopCancer = np.array([])
    tempC_type_two_error = np.array([])
    
    tempListID = 1 
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(H1, tempListID)
    high_risk_region = np.append(high_risk_region, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 2
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(L2, tempListID)
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 3
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(H3, tempListID)    
    high_risk_region = np.append(high_risk_region, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 4
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(H4, tempListID)   
    high_risk_region = np.append(high_risk_region, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 5
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(L5, tempListID)
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 6    
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(L6, tempListID)    
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    tempListID = 7    
    tempID, tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer, temp_type_two_error = find_rep_region(H7, tempListID)    
    high_risk_region = np.append(high_risk_region, tempID)
    tempPopCancer = np.append(tempPopCancer, [tempTotalPop, tempTotalCancer, tempRepPop, tempRepCancer])
    tempC_type_two_error = np.append(tempC_type_two_error, temp_type_two_error)
    
    temp_high_rate = np.array([])
    for region in high_risk_region:
        for rate in reg_rate:
            if int(rate[0]) == int(region):
                temp_high_rate = np.append(temp_high_rate, [region, rate[1]])
                break
    temp_high_rate.shape = (-1,2)

    temp_low_rate = np.array([])    
    for region in low_risk_regioin:
        for rate in reg_rate:
            #print int(rate[0]), int(region)
            if int(rate[0]) == int(region):
                temp_low_rate = np.append(temp_low_rate, [region, rate[1]])
                break        
    temp_low_rate.shape = (-1,2)

    min_high_rate_region = int(temp_high_rate[find_min_id(temp_high_rate[:,1]), 0])
    max_low_rate_region = int(temp_low_rate[find_max_id(temp_low_rate[:,1]), 0])

    min_high_rate = temp_high_rate[find_min_id(temp_high_rate[:,1]), 1]
    max_low_rate = temp_low_rate[find_max_id(temp_low_rate[:,1]), 1]   

    high_region_num = 0
    low_region_num = 0
    for rate in reg_rate[:,1]:
        if rate >= min_high_rate:
            high_region_num = high_region_num + 1
        if rate <= max_low_rate:
            low_region_num = low_region_num + 1
    #print "high_region_num =", high_region_num
    #print "low_region_num = ", low_region_num
    return high_region_num, low_region_num, tempPopCancer, tempC_type_two_error


#--------------------------------------------------------------------------
#MAIN

if __name__ == "__main__":
    #inputs = get_inputs()
    print "begin at " + getCurTime()
    inputAttriCSV = "C:/TP1000_1m.csv"
    popFN = "pop"
    soMethod = "OO"
    filePath = "C:/_DATA/CancerData/test/Jan15/Thousand/67regions/OO_WARD/"

	# returnID used in function find_rep_region

    returnID = 3  # 0: return max_pop, 1: return max_cancer, 2: return max_rate or min_rate, 3: return max_area
    
    while returnID < 4:
        type_two_error = np.array([])
        high_low_measure = np.array([])
        repeat = 1
        PopCancer = np.array([])
        
        while repeat < 1001:
            sInputCSV = filePath + "OO_WARDcancer"+ str(repeat) +".csv"
            sField_Ob = "cancer" + str(repeat)
            attri = build_value_lists_from_csv(sField_Ob) #[[FID, cancer, pop, area],[FID, cancer, pop, area], ... ]
            csv_attri = build_csv_list(sInputCSV)
            dis_reg = np.unique(csv_attri[:,1])
            reg_rate = cal_region_rate(dis_reg)
            temp_high, temp_low, tempPopCancer, temp_type_two_error = calMeaser()
            PopCancer = np.append(PopCancer, tempPopCancer)
            high_low_measure = np.append(high_low_measure, [temp_high, temp_low])
            type_two_error = np.append(type_two_error, temp_type_two_error)
            repeat = repeat + 1

        high_low_measure.shape = (-1,2)

        if returnID == 0:
            txtName_HLM = filePath + soMethod + "_Max_Pop.txt"
            txtName_PC = filePath + soMethod + "_Max_Pop_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Pop_type_two_error.txt"
        elif returnID == 1:
            txtName_HLM = filePath + soMethod + "_Max_Cancer.txt"
            txtName_PC = filePath + soMethod + "_Max_Cancer_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Cancer_type_two_error.txt"
        elif returnID == 2:
            txtName_HLM = filePath + soMethod + "_Max_Rate.txt"
            txtName_PC = filePath + soMethod + "_Max_Rate_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Rate_type_two_error.txt"
        elif returnID == 3:
            txtName_HLM = filePath + soMethod + "_Max_Area.txt"
            txtName_PC = filePath + soMethod + "_Max_Area_PopCancer.txt"
            txtNameTTE = filePath + soMethod + "_Max_Area_type_two_error.txt"

        #print high_low_measure
        np.savetxt(txtName_HLM, high_low_measure, delimiter=',')
        PopCancer.shape = (-1, 28)
        #print PopCancer
        np.savetxt(txtName_PC, PopCancer, delimiter=',')
        type_two_error.shape = (-1, 4)
        np.savetxt(txtNameTTE, type_two_error, delimiter=',')
        
        del type_two_error, high_low_measure, PopCancer, repeat
        returnID = returnID + 1

    print "end at " + getCurTime()
    print "========================================================================"  
    print "========================================================================"
    

    #print "temp_high_rate =", min_high_rate
    #print "temp_low_rate=", max_low_rate
    #print temp_high_rate, temp_low_rate
    #print high_risk_region, low_risk_regioin

    #output_results()  

           
